package com.innovation.chengzhangriji.ui;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Point;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.innovation.chengzhangriji.Baby;
import com.innovation.chengzhangriji.BabyAndParent;
import com.innovation.chengzhangriji.Config;
import com.innovation.chengzhangriji.R;
import com.innovation.chengzhangriji.database.DatabaseManager;
import com.innovation.chengzhangriji.http.AllBabyResponse;
import com.innovation.chengzhangriji.http.Auth;
import com.innovation.chengzhangriji.http.Client;
import com.innovation.chengzhangriji.http.NewMessageResponse;
import com.innovation.chengzhangriji.http.ResponseHandler;
import com.innovation.chengzhangriji.preferences.LoginInfo;
import com.innovation.chengzhangriji.ui.widget.MenuView;
import com.orhanobut.logger.Logger;

import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.PeriodType;

public class TimelineActivity extends BaseLoginActivity implements MenuView.OnClickMenuListener {

    private TimelineEmptyFragment mEmptyFragment;

    private TimelineFragment mFragment;

    private DrawerLayout mDrawerLayout;

    private MenuView menuView;

    private ChangeReceiver receiver;

    private boolean show;

    private DeleteBroadcastReceiver deleteBroadcastReceiver;

    private boolean delete;

    private static final int REQUEST_CODE_EDIT = 100;

    private static final int REQUEST_CODE_EDIT_DIALOG = 101;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_EDIT && resultCode == RESULT_OK) {
            LoginInfo loginInfo = Config.getLoginInfo(this);
            if (loginInfo == null) {
                return;
            }
            String name;
            if (!TextUtils.isEmpty(loginInfo.getName())) {
                name = loginInfo.getName();
            } else {
                name = loginInfo.getPhone();
            }
            menuView.setHeadUrl(loginInfo.getUrl());
            menuView.setName(name);
        } else if (requestCode == REQUEST_CODE_EDIT_DIALOG && resultCode == RESULT_OK) {
            onClickEditUserInfo();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LoginInfo loginInfo = Config.getLoginInfo(this);
        if (loginInfo == null) {
            return;
        }

        if (TextUtils.isEmpty(loginInfo.getName()) && !loginInfo.isHasTipEdit()) {
            Intent intent = new Intent(this, EditUserInfoDialogActivity.class);
            startActivityForResult(intent, REQUEST_CODE_EDIT_DIALOG);
        }

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("change");
        receiver = new ChangeReceiver();
        LocalBroadcastManager.getInstance(this).registerReceiver(receiver, intentFilter);

        IntentFilter intentFilter2 = new IntentFilter();
        intentFilter2.addAction("delete");
        deleteBroadcastReceiver = new DeleteBroadcastReceiver();
        LocalBroadcastManager.getInstance(this).registerReceiver(deleteBroadcastReceiver, intentFilter2);

        setupLayout(loginInfo);
        Config.startSyncTimelineService(this);
        fragmentTransaction(getBaby(loginInfo));

        updateMiPushToken();
    }

    @Override
    protected void onResume() {
        super.onResume();

        LoginInfo loginInfo = Config.getLoginInfo(this);
        if (loginInfo == null) {
            return;
        }
        String userID = loginInfo.getUserID();
        String phone = loginInfo.getPhone();
        String token = loginInfo.getToken().getAccessToken();
        int babyID = loginInfo.getBabyID();
        final long serverTS = DatabaseManager.getInstance(this).queryMessageServerTS(userID);

        if (delete) {
            delete = false;
            getAllBabyInfo(loginInfo, babyID);
            return;
        }

        if (mFragment != null) {
            mFragment.setVisibilityPointMsg(Config.getHasNewMessage(this) || Config.getHasNewComment(this));
        }

        // TODO 未来推送获取,不再主动拉取.
        Client.requestNewMessage(this, phone, token, babyID, serverTS, new ResponseHandler() {

            @Override
            public void onInnovationSuccess(JsonElement value) {

                NewMessageResponse response = get(value.toString(), NewMessageResponse.class);
                if (response == null) {
                    return;
                }
                if (response.getServerTS() > serverTS) {
                    show = true;
                    Logger.d("有新消息");
                    Config.startGetAllBabyInfoService(TimelineActivity.this);
                    menuView.setVisibilityPoint(View.VISIBLE);
                    if (mEmptyFragment != null) {
                        mEmptyFragment.setVisibilityPoint(true);
                    }
                    if (mFragment != null) {
                        mFragment.setVisibilityPoint(true);
                    }
                } else {
                    show = false;
                    menuView.setVisibilityPoint(View.INVISIBLE);
                    if (mEmptyFragment != null) {
                        mEmptyFragment.setVisibilityPoint(false);
                    }
                    if (mFragment != null) {
                        mFragment.setVisibilityPoint(false);
                    }
                }
            }

        }, networkUnavailableSampleImpl());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
        LocalBroadcastManager.getInstance(this).unregisterReceiver(deleteBroadcastReceiver);
    }

    @Override
    public void onBackPressed() {
        if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) {
            mDrawerLayout.closeDrawer(Gravity.LEFT);
            return;
        }
        super.onBackPressed();
    }

    @Override
    protected void receiveChZhRJMessage(int type, int tag) {
        if (type == 1) {
            if (mFragment != null) {
                mFragment.setVisibilityPointMsg(true);
            }
        }
    }

    @Override
    public void onClickClose() {
        mDrawerLayout.closeDrawer(Gravity.LEFT);
    }

    @Override
    public void onClickEditUserInfo() {
        Intent intent = new Intent(this, EditUserInfoActivity.class);
        startActivityForResult(intent, REQUEST_CODE_EDIT);
    }

    @Override
    public void onClickMessages() {
        // 判断是否有网络
        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        if (networkInfo == null) {
            tipShow("网络不给力哦,请稍候再来查看吧!");
            return;
        }
        mDrawerLayout.closeDrawer(Gravity.LEFT);
        Intent intent = new Intent(this, MessagesActivity.class);
        startActivity(intent);
    }

    @Override
    public void onClickSettings() {
        mDrawerLayout.closeDrawer(Gravity.LEFT);
        Intent intent = new Intent(this, SettingsActivity.class);
        startActivity(intent);
    }

    @Override
    public void onClickConnectDevice() {
        Intent intent = new Intent(this, ConnectDeviceActivity.class);
        startActivity(intent);
    }

    @Override
    public void onClickNote(int position) {
        LoginInfo loginInfo = Config.getLoginInfo(this);
        if (loginInfo != null) {
            this.position = position;
            change = true;
            mDrawerLayout.closeDrawer(Gravity.LEFT);
        }
    }

    private int position;

    private boolean change;

    private void change() {
        if (!change) {
            return;
        }
        change = false;
        LoginInfo loginInfo = Config.getLoginInfo(this);
        String userID = loginInfo.getUserID();
        int babyID = queryBabyID(userID, position);
        loginInfo.setBabyID(babyID);
        Gson gson = new Gson();
        String loginValue = gson.toJson(loginInfo);
        Config.setLoginInfo(this, loginValue);
        loginInfo = Config.getLoginInfo(this);
        Baby baby = getBaby(loginInfo);
        Config.startSyncTimelineService(this);
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = manager.beginTransaction();
        mFragment = new TimelineFragment();
        fragmentTransaction.replace(R.id.content_timeline, mFragment);
        fragmentTransaction.commitAllowingStateLoss();
        mFragment.setBabyHead(getHeadUrl(baby));
        mFragment.setNoteName(getNoteName(baby));
        mFragment.setBabyDay(getBabyDay(baby));
    }

    @Override
    public void onLongClickNote(final int position) {

        // 网络请求删除
        final LoginInfo loginInfo = Config.getLoginInfo(TimelineActivity.this);
        if (loginInfo == null) {
            return;
        }
        final String phone = loginInfo.getPhone();
        final String token = loginInfo.getToken().getAccessToken();
        final String userID = loginInfo.getUserID();
        final int babyID = queryBabyID(userID, position);
        // 判断权限
        BabyAndParent babyAndParent = DatabaseManager.getInstance(TimelineActivity.this).queryBabyAndParent(userID, babyID);
        if (babyAndParent.getRole() == 2) {
            Intent intent = new Intent(TimelineActivity.this, TipDeleteDialogActivity.class);
            startActivity(intent);
            return;
        }

        new AlertDialog.Builder(this).setTitle("取消对日记本的关注")
                .setPositiveButton("是", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Client.requestRemoveNote(TimelineActivity.this, phone, token, babyID, new ResponseHandler() {

                            @Override
                            public void onInnovationStart() {
                                showProgressDialog(null, null);
                            }

                            @Override
                            public void onInnovationSuccess(JsonElement value) {
                                getAllBabyInfo(loginInfo, babyID);
                                dismissProgressDialog();
                            }

                            @Override
                            public void onChZhRJFailure(String value) {
                                dismissProgressDialog();
                                tipShow(value);
                            }

                            @Override
                            public void onChZhRJTokenFailure(String value) {
                                dismissProgressDialog();
                                tipShow(value);
                            }

                        }, networkUnavailableSampleImpl());
                    }
                })
                .setNegativeButton("否", null)
                .show();
    }

    public void openDrawer() {
        mDrawerLayout.openDrawer(Gravity.LEFT);
    }

    public void setMenuHead(String url, String name) {
        menuView.setHead(url, name);
    }

    private void setupLayout(LoginInfo loginInfo) {
        setContentView(R.layout.activity_timeline);
        menuView = (MenuView) findViewById(R.id.menu);
        String name;
        if (!TextUtils.isEmpty(loginInfo.getName())) {
            name = loginInfo.getName();
        } else {
            name = loginInfo.getPhone();
        }
        menuView.setHeadUrl(loginInfo.getUrl());
        menuView.setName(name);
        menuView.setOnClickMenuListener(this);
        int position = DatabaseManager.getInstance(this).queryBabyPosition(loginInfo.getUserID(), loginInfo.getBabyID());
        menuView.setPosition(position);
        menuView.setNotes(getBabyAll(loginInfo));
        WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        Point size = new Point();
        window.getDefaultDisplay().getSize(size);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerLayout.setDrawerShadow(getResources().getDrawable(R.drawable.drawer_shadow), Gravity.LEFT);
        mDrawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {

            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {

            }

            @Override
            public void onDrawerOpened(View drawerView) {

            }

            @Override
            public void onDrawerClosed(View drawerView) {
                change();
            }

            @Override
            public void onDrawerStateChanged(int newState) {

            }
        });
    }

    private void fragmentTransaction(Baby baby) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = manager.beginTransaction();
        if (baby == null) {
            mEmptyFragment = new TimelineEmptyFragment();
            fragmentTransaction.replace(R.id.content_timeline, mEmptyFragment);
        } else {
            mFragment = new TimelineFragment();
            mFragment.setBabyHead(getHeadUrl(baby));
            mFragment.setNoteName(getNoteName(baby));
            mFragment.setBabyDay(getBabyDay(baby));
            fragmentTransaction.replace(R.id.content_timeline, mFragment);
        }
        fragmentTransaction.commitAllowingStateLoss();
    }

    private Baby[] getBabyAll(LoginInfo loginInfo) {
        String userID = loginInfo.getUserID();
        return DatabaseManager.getInstance(this).queryBabyAll(userID);
    }

    private int queryBabyID(String userID, int position) {
        return DatabaseManager.getInstance(this).queryBabyID(userID, position);
    }

    private Baby getBaby(LoginInfo loginInfo) {
        String userId = loginInfo.getUserID();
        int babyID = loginInfo.getBabyID();
        if (babyID == LoginInfo.EMPTY_BABY_ID) {
            return null;
        }
        return DatabaseManager.getInstance(this).queryBaby(userId, babyID);
    }

    private String getNoteName(Baby baby) {
        return baby.getName();
    }

    private String getBabyDay(Baby baby) {
        switch (baby.getState()) {
            case Client.STATE_READY:
                return "备孕中";
            case Client.STATE_START:
                if (baby.getDueDate() != 0) {
                    return getBabyDayByDueDateOrLastDate(baby.getDueDate() - 280 * 24 * 60 * 60 * 1000l);
                } else {
                    return getBabyDayByDueDateOrLastDate(baby.getLastDate());
                }
            case Client.STATE_END:
                return getBabyDayByBirthday(baby.getBirthday());
        }
        return null;
    }

    private String getBabyDayByDueDateOrLastDate(long time) {
        DateTime startTime = new DateTime(time);
        DateTime endTime = new DateTime(System.currentTimeMillis());
        Period pWeek = new Period(startTime, endTime, PeriodType.weeks());
        String week = "";
        String day = "";
        if (pWeek.getWeeks() != 0) {
            week = pWeek.getWeeks() + "周";
        }
        Period pDay = new Period(startTime, endTime, PeriodType.yearWeekDay());
        if (pDay.getDays() != 0) {
            day = pDay.getDays() + "天";
        }
        if (TextUtils.isEmpty(week) && TextUtils.isEmpty(day)) {
            return "孕1天";
        }
        return "孕" + week + day;
    }

    private String getBabyDayByBirthday(long birthday) {
        DateTime startTime = new DateTime(birthday);
        DateTime endTime = new DateTime(System.currentTimeMillis());
        Period p = new Period(startTime, endTime, PeriodType.yearMonthDay());
        String year = "";
        String month = "";
        String day = "";
        if (p.getYears() != 0) {
            year = p.getYears() + "岁";
        }
        if (p.getMonths() != 0) {
            month = p.getMonths() + "月";
        }
        if (p.getDays() != 0) {
            day = p.getDays() + "天";
        }
        return year + month + day;
    }

    private String getHeadUrl(Baby baby) {
        return baby.getImageUrl();
    }

    private void getAllBabyInfo(final LoginInfo loginInfo, final int removeBabyID) {
        final String id = loginInfo.getUserID();
        final String phone = loginInfo.getPhone();
        final String token = loginInfo.getToken().getAccessToken();
        Client.requestAllBaby(this, phone, token, new ResponseHandler() {

            @Override
            public void onInnovationStart() {
                showProgressDialog(null, null);
            }

            @Override
            public void onInnovationSuccess(JsonElement value) {
                AllBabyResponse response = get(value.toString(), AllBabyResponse.class);
                // 修改为直接进入Timeline
                if (response != null) {
                    setLoginInfo(loginInfo);
                    int length = response.getData().length;
                    int[] childIDArray = new int[length];
                    Auth[] auth = new Auth[length];
                    for (int i = 0; i < length; i++) {
                        childIDArray[i] = response.getData()[i].getId();
                        auth[i] = response.getData()[i].getAuth();
                    }
                    insertOrReplaceInTxBabyAndParent(id, auth, childIDArray);
                    insertOrReplaceInTxBaby(response.getData());
                    LoginInfo newLoginInfo = Config.getLoginInfo(TimelineActivity.this);
                    if (newLoginInfo == null) {
                        return;
                    }
                    if (loginInfo.getBabyID() == removeBabyID && childIDArray.length == 0) {
                        newLoginInfo.setBabyID(LoginInfo.EMPTY_BABY_ID);
                        Gson gson = new Gson();
                        String loginValue = gson.toJson(newLoginInfo);
                        Config.setLoginInfo(TimelineActivity.this, loginValue);
                        fragmentTransaction(null);
                    } else if (loginInfo.getBabyID() == removeBabyID && childIDArray.length > 0) {
                        newLoginInfo.setBabyID(childIDArray[0]);
                        Gson gson = new Gson();
                        String loginValue = gson.toJson(newLoginInfo);
                        Config.setLoginInfo(TimelineActivity.this, loginValue);
                        newLoginInfo = Config.getLoginInfo(TimelineActivity.this);
                        Baby baby = getBaby(newLoginInfo);
                        Config.startSyncTimelineService(TimelineActivity.this);
                        FragmentManager manager = getSupportFragmentManager();
                        FragmentTransaction fragmentTransaction = manager.beginTransaction();
                        mFragment = new TimelineFragment();
                        fragmentTransaction.replace(R.id.content_timeline, mFragment);
                        fragmentTransaction.commitAllowingStateLoss();
                        mFragment.setBabyHead(getHeadUrl(baby));
                        mFragment.setNoteName(getNoteName(baby));
                        mFragment.setBabyDay(getBabyDay(baby));
                    }
                    menuView.cleanNotes();
                    int position = DatabaseManager.getInstance(TimelineActivity.this).queryBabyPosition(newLoginInfo.getUserID(), newLoginInfo.getBabyID());
                    menuView.setPosition(position);
                    menuView.setNotes(getBabyAll(newLoginInfo));
                }
                dismissProgressDialog();
            }

            @Override
            public void onChZhRJFailure(String value) {
                dismissProgressDialog();
                tipShow(value);
            }

            @Override
            public void onChZhRJTokenFailure(String value) {
                dismissProgressDialog();
                tipShow(value);
            }

        }, networkUnavailableSampleImpl());
    }

    private void updateMiPushToken() {
        Logger.d("1");
        LoginInfo loginInfo = Config.getLoginInfo(this);
        if (loginInfo == null) {
            return;
        }
        Logger.d("2");
        if (TextUtils.isEmpty(Config.getMiPushId(this))) {
            return;
        }
        Logger.d("3");
        if (Config.getMiPushIdSuccess(this)) {
            return;
        }
        String phone = loginInfo.getPhone();
        String token = loginInfo.getToken().getAccessToken();
        Logger.d("准备推送");
        Client.requestPushToken(this, phone, token, Config.getMiPushId(this), new ResponseHandler() {

            @Override
            public void onInnovationSuccess(JsonElement value) {
                Logger.d("推送成功");
                Config.setMiPushIdSuccess(TimelineActivity.this, true);
            }

            @Override
            public void onChZhRJFailure(String value) {
                super.onChZhRJFailure(value);
                Logger.d("推送失败");
            }

            @Override
            public void onInnovationExceptionFinish() {
                super.onInnovationExceptionFinish();
                Logger.d("推送超时");
            }
        }, networkUnavailableSampleImpl());
    }

    private class ChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            LoginInfo loginInfo = Config.getLoginInfo(TimelineActivity.this);
            if (loginInfo == null) {
                return;
            }
            LoginInfo newLoginInfo = Config.getLoginInfo(TimelineActivity.this);
            if (newLoginInfo == null) {
                return;
            }
            String userId = loginInfo.getUserID();
            int babyId = loginInfo.getBabyID();
            Baby baby = getBaby(loginInfo);
            boolean refresh = true;
            if (baby == null) {
                Baby[] babies = DatabaseManager.getInstance(TimelineActivity.this).queryBabyAll(userId);
                if (babies == null || babies.length == 0) {
                    refresh = false;
                    newLoginInfo.setBabyID(LoginInfo.EMPTY_BABY_ID);
                    Gson gson = new Gson();
                    String loginValue = gson.toJson(newLoginInfo);
                    Config.setLoginInfo(TimelineActivity.this, loginValue);
                    fragmentTransaction(null);
                } else {
                    if (babyId == LoginInfo.EMPTY_BABY_ID) {
                        refresh = false;
                        fragmentTransaction(null);
                    } else {
                        refresh = true;
                        newLoginInfo.setBabyID(babies[0].getBabyID());
                        Gson gson = new Gson();
                        String loginValue = gson.toJson(newLoginInfo);
                        Config.setLoginInfo(TimelineActivity.this, loginValue);
                        baby = getBaby(newLoginInfo);
                    }
                }
            }
            if (refresh) {
                Config.startSyncTimelineService(TimelineActivity.this);
                FragmentManager manager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = manager.beginTransaction();
                mFragment = new TimelineFragment();
                mFragment.setBabyHead(getHeadUrl(baby));
                mFragment.setNoteName(getNoteName(baby));
                mFragment.setBabyDay(getBabyDay(baby));
                fragmentTransaction.replace(R.id.content_timeline, mFragment);
                fragmentTransaction.commitAllowingStateLoss();
            }

            if (show) {
                menuView.setVisibilityPoint(View.VISIBLE);
                if (mEmptyFragment != null) {
                    mEmptyFragment.setVisibilityPoint(true);
                }
                if (mFragment != null) {
                    mFragment.setVisibilityPoint(true);
                }
            } else {
                show = false;
                menuView.setVisibilityPoint(View.INVISIBLE);
                if (mEmptyFragment != null) {
                    mEmptyFragment.setVisibilityPoint(false);
                }
                if (mFragment != null) {
                    mFragment.setVisibilityPoint(false);
                }
            }

            menuView.cleanNotes();
            int position = DatabaseManager.getInstance(TimelineActivity.this).queryBabyPosition(newLoginInfo.getUserID(), newLoginInfo.getBabyID());
            menuView.setPosition(position);
            menuView.setNotes(DatabaseManager.getInstance(TimelineActivity.this).queryBabyAll(userId));
        }
    }

    private class DeleteBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            delete = true;
        }
    }
}
